﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Threading;
using System.Text.RegularExpressions;

using GTServices.Model.CoRoutine;
using Caliburn.Micro;
using GTServices.Entities;
using GTServices.Model.Extensions;
using GTServices.Model.Exceptions;
using IO = System.IO;

namespace GTServices.Model.Models
{
    public class GrepModel
    {
        public static Category DEFAULT_CATEGORY = new Category()
        {
           Name = "Anonymous Issue"
           
        };
        public static int SearchID = 1; 

        public bool   Recurse { get; set; }

        public FileManagerModel FilesModel { get; set; }
        public DataModel DataModel { get; set; }
       
        public GrepModel()
        {
            this.Recurse = true;
        }

        public GrepRequest GetGrepRequest(String rootDirectory, IList<Pattern> patterns, IList<Language> languages, IList<Category> categories = null, IList<FileExtension> extensions = null)
        {
            if (!IO.Directory.Exists(rootDirectory))
            {
                throw new ArgumentException("Directory does no exist: " + rootDirectory);
            }

            if (patterns.Count < 1)
            {
                throw new ArgumentException("No patterns selected.");
            }

            //Validate the Regexs.
            foreach (Pattern p in patterns)
            {
                if (!p.IsValidPattern())
                {
                    throw new ArgumentException(String.Format("Invalid Pattern Id{0} String{1}: ", p.Id.ToString(), p.PatternStr));
                }
            }


            //If the patterns belong to no issues in the set we need to attribute them to the anonymous issue. 
            if (categories == null)
            {
                categories = new List<Category>();
            }

            if (categories.Count == 0)
            {
                Category c = new Category() { Name = DEFAULT_CATEGORY.Name };
                patterns.ForEach(x => c.Patterns.Add(x));
                categories.Add(c);
            }
            else
            {
                var allIssuePatterns = categories.SelectMany(x => x.Patterns);
                var nonIssuePatterns = patterns.Where(x => !allIssuePatterns.Contains(x));

                Category c = new Category() { Name = DEFAULT_CATEGORY.Name };
                nonIssuePatterns.ForEach(x => c.Patterns.Add(x));
            }

            if (extensions == null)
                extensions = patterns.Where(x => x.Language != null && x.Language.Name != "All").SelectMany((x) => x.Language.FileExtensions).Distinct().ToList();

            GrepRequest gr = new GrepRequest()
            {
                RootPath = rootDirectory,
                Recursive = Recurse,
                Categories = categories,
                Patterns = patterns,
                Languages = languages,
                FileExtensions = extensions
            };


            return gr;
        }
    }
}
